/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package JFreeChartExtensions;

import JFreeChartExtensions.chartextensions.AbstractChartPanelExtension;
import JFreeChartExtensions.exceptions.ExtensionLauncherException;
import JFreeChartExtensions.interfaces.Plugin;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Nobody
 */
public class ExtensionManager {

    private ExtendableChartPanel chartPanel;

    public ExtensionManager(ExtendableChartPanel chartPanel) {
        this.chartPanel = chartPanel;
    }

    public ExtensionManager() {
    }
    private Map<String, AbstractChartPanelExtension> abstractChartPanelExtensions = new HashMap<String, AbstractChartPanelExtension>();
    /*
    public void launchExtensions() throws ExtendableChartPanelException {
    List<Plugin> plugins = Main.getInstance().getConfiguration().getPlugins();
    for (Plugin plugin : plugins) {
    try {
    if (plugin.isAvailable()) {
    AbstractChartPanelExtension extension = tryToCreateExtension(plugin, chartPanel);
    addExtension(extension);
    }
    } catch (ExtensionLauncherException ex) {
    throw new ExtendableChartPanelException("exception during adding extensions", ex);
    }
    }
    }

    public void addExtension(AbstractChartPanelExtension abstractChartPanelExtension) throws ExtendableChartPanelException {
    try {
    abstractChartPanelExtension.applyExtension(chartPanel);
    abstractChartPanelExtensions.put(abstractChartPanelExtension.getName(), abstractChartPanelExtension);
    } catch (ExtensionLauncherException ex) {
    throw new ExtendableChartPanelException("exception in adding extenstion : " + abstractChartPanelExtension.getName(), ex);
    }
    }

    public void removeExtension(String name) {
    AbstractChartPanelExtension extension = abstractChartPanelExtensions.get(name);
    if (extension != null) {
    extension.removeExtension();
    }
    abstractChartPanelExtensions.remove(name);
    chartPanel.updateChart();

    }

    public AbstractChartPanelExtension getExtensionByName(String name) {
    return abstractChartPanelExtensions.get(name);
    }

    public Map<String, AbstractChartPanelExtension> getChartPanelExtensions() {
    return abstractChartPanelExtensions;
    }

    public boolean hasExtension(String string) {
    return abstractChartPanelExtensions.containsKey(string);
    }
     */

    public AbstractChartPanelExtension tryToCreateExtension(Plugin plugin, ExtendableChartPanel panel) throws ExtensionLauncherException {
        try {
            return createExtension(plugin, panel);
        } catch (NoSuchMethodException ex) {
            throw new ExtensionLauncherException(plugin, ex);
        } catch (SecurityException ex) {
            throw new ExtensionLauncherException(plugin, ex);
        } catch (InstantiationException ex) {
            throw new ExtensionLauncherException(plugin, ex);
        } catch (IllegalAccessException ex) {
            throw new ExtensionLauncherException(plugin, ex);
        } catch (IllegalArgumentException ex) {
            throw new ExtensionLauncherException(plugin, ex);
        } catch (InvocationTargetException ex) {
            throw new ExtensionLauncherException(plugin, ex);
        } catch (ClassNotFoundException ex) {
            throw new ExtensionLauncherException(plugin, ex);
        }
    }

    private AbstractChartPanelExtension createExtension(Plugin plugin, ExtendableChartPanel panel) throws NoSuchMethodException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        try {
            URLClassLoader child = new URLClassLoader(new URL[]{new File("lib\\jfreechartextension.jar").toURI().toURL()});
            Constructor c = Class.forName(plugin.getClasspath(), true, child).getConstructor(panel.getClass());
            return (AbstractChartPanelExtension) c.newInstance(panel);
        } catch (MalformedURLException ex) {
            Logger.getLogger(ExtensionManager.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }
}
